package com.bjh.netty.server;

import com.bjh.netty.codec.RpcDecoder;
import com.bjh.netty.codec.RpcEncoder;
import com.bjh.netty.message.RpcMessage;
import com.bjh.req.Request;
import com.bjh.resp.Response;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class RpcServer {

    private Integer port;

    private EventLoopGroup bossGroup;

    private EventLoopGroup workerGroup;

    private ServerBootstrap serverBootstrap;


    public RpcServer(Integer port) {
        this.port = port;
    }

    public void start() {
        try{
            this.bossGroup = new NioEventLoopGroup(1);
            this.workerGroup = new NioEventLoopGroup();

            this.serverBootstrap = new ServerBootstrap();

            serverBootstrap.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new RpcDecoder(RpcMessage.class));
                            pipeline.addLast(new RpcEncoder(RpcMessage.class));
                            pipeline.addLast(new RpcServerHandler());
                        }
                    });

            log.info("Netty Server start success...............................");
            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();

            channelFuture.channel().closeFuture().sync();
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            close();
        }
    }

    public void close() {
        this.bossGroup.shutdownGracefully();
        this.workerGroup.shutdownGracefully();
    }


    public static void main(String[] args) {
        RpcServer rpcServer = new RpcServer(9090);
        rpcServer.start();
    }
}
